/******************************************************************
文件名	：main.c
功能 	：lcd.c中函数功能的demo
		  详情请看lcd.c里的注释和源码
版本	： 
时间	：2017.10.24
作者	：王理洁
联系方式：wanglijie201710@163.com
******************************************************************
LCD 显示的过程：
*定义一个数组 unsigned int virtual_lcd[480][800] 作为虚拟显存
*每次显示内容，先将内容画在虚拟显存上（调用draw_xxx函数）。
*要显示什么就画什么，要显示几个就画几个（两次画在同一位置，新的会覆盖旧的）
*全部画完之后，把虚拟显存上的东西显示出来（调用show_lcd_now函数）

本例程包括以下几个函数：
struct touch_screen_data touch_screen(void);		//触屏
struct cross_screen_data cross_screen(void);		//划屏
int draw_block(lcd_block * block);					//画色块
int draw_box(lcd_box * box)	;						//画方框
int draw_text(lcd_text * text );					//画文本
int draw_button(lcd_button * button);				//画按钮（只能画矩形按钮）
int draw_bmp(int x,int y,const char *filename);		//画bmp图
int show_lcd_now(void);								//将画的内容显示出来
int press_button(int num_of_button,...);			//按按钮函数，可以配置按下按钮要做的事

**********************************
注意：1.字库路径
		使用显示文本功能，必须要把字库文件放到开发板上，
		本demo默认需要将【fontlibrary文件及里面的字库文件】整体放到开发板/目录（根目录）下，
		如果要放到别的路径，请到lcd.c文件中找到这句话：sprintf(filename,"/fontlibrary/%c%d.bin",text->type,text->size);  去修改字库文件的路径
	  3.使用时在你的工程中包含lcd.c,font.c,lcd.h,font.h 这四个文件，并一同编译
	  2.本demo使用的测试图片103x100.bmp要和本demo的可执行文件放在同一个目录下
**********************************

******************************************************************/


#include  <stdio.h>

#include  "lcd.h"

void * begin_rouetin(void * arg);									//开始按钮的回调函数，格式固定，和创建子线程pthread_creat的回调函数格式一样


int main()
{
	
/***************  draw_block 画色块  ********************/
	lcd_block  block;												//定义一个色块(结构体)
	
	
	block.x0			= 0;										//块左上角x坐标
	block.y0			= 0;										//块左上角y坐标
	block.width			= 800;										//块宽度
	block.height		= 480;										//块高度
	block.color			= PURPLE;									//填充色(lcd.h里有部分颜色的宏定义)
	draw_block(&block);												//将色块画到虚拟显存（一个数组），并不会马上显示出来
	printf("[主函数： ] 用draw_block画出背景 800*480，紫色\n");
	
	
	block.x0			= 50;										//块左上角x坐标
	block.y0			= 50;										//块左上角y坐标
	block.width			= 200;										//块宽度
	block.height		= 50;										//块高度
	block.color			= RED;										//填充色(lcd.h里有部分颜色的宏定义)
	draw_block(&block);												//将色块画到虚拟显存（一个数组），并不会马上显示出来
	printf("[主函数： ] 从（50，50）开始画一个200*50的色块，红色\n");
	
	
	
	
	
/***************  draw_box 画方框  ********************/
	lcd_box	box;													//定义一个矩形（结构体）
	
	box.x0			= 300;											//矩形左上角x坐标
	box.y0			= 50;											//矩形左上角y坐标
	box.width		= 200;											//矩形宽度
	box.height		= 50;											//矩形高度
	box.line_width	= 5;											//线宽，在方框的框线宽度
																	//线宽向矩形内生长，矩形总大小由height，height两个参数指定
																	//线完为0则没有框线
	box.line_color	= RED;											//线色
	box.fill_color	= BLUE;											//矩形填充色
	draw_box(&box);													//将方框画到虚拟显存（一个数组），并不会马上显示出来
	printf("[主函数： ] 从（300，50）开始画一个200*50的方框，颜色蓝色，外面有框线，框线宽度是5，红色\n");

	
/***************  draw_text 写文本  ********************/
	lcd_text text;													//定义文本（结构体）
	
	char text_buf[128] = "隔壁小王2017";							//存文本的buf
	
	
	text.type				= 's';									//字体			----传入ASCII码 ‘s’ ‘k’ ‘h’ ‘w’ 分别对应 仿宋，楷体，黑体，微软雅黑 
	text.size				= 24;									//字号			----支持6个字号：16 24 32 40 48 56，16号既为16*16个像素点
	text.character			= text_buf;								//要打印的字串	----可以是英文或中文
	text.x					= 50;									//起始位置的X坐标
	text.y					= 120;									//起始位置的Y坐标	
	text.color_character	= GREEN;								//字体颜色		----传入 32bit ARGB 颜色值
	text.color_background	= RED;									//字体背景颜色	----值为0xFFFFFFFF时背景为透明，不覆盖原来的内容
	draw_text(&text);												//将文本画到虚拟显存（一个数组），并不会马上显示出来
	printf("[主函数： ] 从（50，120）开始，显示一行文体，字体是宋体，字号24*24像素，文本内容是“隔壁小王2017”，字体颜色绿色，字体背景红色\n");
	
	
	text.character			= "赵钱孙李，周吴郑王";	
	text.x					= 50;			
	text.y					= 170;	
	text.color_background	= 0xFFFFFFFF;
	draw_text(&text);												//将文本画到虚拟显存（一个数组），并不会马上显示出来
	printf("[主函数： ] 从（50，170）开始，显示一行文体，字体是宋体，字号24*24像素，文本内容是“赵钱孙李，周吴郑王”，字体颜色绿色，字体背景透明\n");
	
	
	
	
/***************  draw_button 画一个button  ********************/
	lcd_button begin;												//定义一个button(结构体)
	
	begin.text_flag	 = 1;											//如果button有字此标志位应该置1，否则应置0
	begin.reverse_color = GREEN;									//button的反显颜色,即按下button要显示的颜色
	
	begin.box.x0			= 50;									//矩形左上角x坐标
	begin.box.y0			= 220;									//矩形左上角y坐标
	begin.box.width			= 200;									//矩形宽度
	begin.box.height		= 50;									//矩形高度
	begin.box.line_width	= 5;									//线宽，在方框的框线宽度
	begin.box.line_color	= RED;									//线色
	begin.box.fill_color	= BLUE;									//矩形填充色
	
	begin.text.type				= 'k';								//字体			----传入ASCII码 ‘s’ ‘k’ ‘h’ ‘w’ 分别对应 仿宋，楷体，黑体，微软雅黑 
	begin.text.size				= 24;								//字号			----支持6个字号：16 24 32 40 48 56，16号既为16*16个像素点
	begin.text.character			= "开始";						//要打印的字串	----可以是英文或中文
	begin.text.x					= 120;							//起始位置的X坐标
	begin.text.y					= 233;							//起始位置的Y坐标	
	begin.text.color_character		= GREEN;						//字体颜色		----传入 32bit ARGB 颜色值
	begin.text.color_background	= 0xFFFFFFFF;						//字体背景颜色	----值为0xFFFFFFFF时背景为透明，不覆盖原来的内容
	
	draw_button(&begin);											//将button画到虚拟显存（一个数组），并不会马上显示出来
	printf("[主函数： ] 画出开始按钮，详情看源代码吧\n");
	

	
	
/***************  draw_bmp 画一张bmp图  ********************/
	draw_bmp(400,240,"103x100.bmp");								//从（400，240）开始画出103x100.bmp(宽103，高100)
	printf("[主函数： ] 从（400，240）开始画出103x100.bmp(宽103，高100)\n");
	draw_bmp(750,430,"103x100.bmp");										//从（750，430）开始画出103x100.bmp(测试是否会因数组越界导致段错误)
	printf("[主函数： ] 从（400，240）从（750，430）开始画出103x100.bmp(测试是否会因数组越界导致段错误)\n");
	
	
/***************  show_lcd_now 显示虚拟显存（一个数组）的内容  ********************/
	show_lcd_now();													//画了一个或多个对角之后，将虚拟显存（一个数组）的容显示到lcd上
																
																			/***************************************
																			int show_lcd_now(void)
																			{
																				open_lcd();											//open LCD 
																				memcpy(fd_mem,virtual_lcd,sizeof(virtual_lcd));	//将虚拟显存（数组unsigned int virtual_lcd[400][800]）的内容 copy 到 LCD 显存
																				close_lcd();										//关闭LCD
																				return 0;
																			}
																			***************************************/
	printf("[主函数： ] 画了这么多，其实一直没显示出来，调用show_lcd_now函数，把上面画的都显示出来\n");										
											
	printf("请按开始按钮，开始测试触摸和划屏\n");	
	
	
/***************  press_button 点击button函数  ********************/	
	press_button(2, &begin, begin_rouetin, NULL);					//调用press_button函数，等待button被按下
																			/*******************************************************************
																			函数名	：	press_button
																			功能  	：	阻塞等待button被按下，按下后对button进行反显；
																						松开按钮或触摸位置移动到按钮之外，调用按键指定的回调函数;
																						第次调用本函数，只能响应按下的一个铵钮，没按下的按钮不响应；
																						如果没有按到任何指定按钮，则继续等待
																			参数  	：	int num_of_button 					按键的个数（最少1个（不然你调用它干嘛），理论上无上限）
																						lcd_button * button0				lcd_button 类型指针，指向button0
																						void *(*button0_routine)(void *)	button0的回调函数（使用时注意格式，格式和pthread_create创建子线程的回调函数一样）
																						void * button0_arg					button0加调函数的参数
																						...									后面再加button,如上button0的格式，每个button要传入3个参数

																			返回值	：	0			
																			描述	：	注意：num_of_button是button的个数，不是传入参数的总个数			
																			*******************************************************************/
													
	return 0;
}



void * begin_rouetin(void * arg)									//开始按钮的回调函数，格式固定，和创建子线程pthread_creat的回调函数格式一样
{
	
	struct touch_screen_data position; 								//定义一个position（struct touch_screen_data类型的结构体），用来接收touch_screen返回的坐标
	int i = 10;
	while(i)
	{
		printf("[开始按钮回调函数： ] 请点击屏幕任意位置测试触屏（touch_screen函数），点 %d 次将进入划屏测试\n",i--);
		
		position = touch_screen();									//touch_screen会阻塞等待，点击屏幕后会返回点到的x,y坐标
																			/*********************************
																			struct touch_screen_data
																				{
																					int x;		//x坐标
																					int y;		//y坐标
																				};
																			**********************************/
		printf("[开始按钮回调函数： ] touch_screen函数返回的结果：\n");
		printf("[开始按钮回调函数： ] position.x = %d\n",position.x);
		printf("[开始按钮回调函数： ] position.y = %d\n",position.y);
		printf("\n");
		
	}
	

	printf("[开始按钮回调函数： ] 下面开始测试划屏\n");
	struct cross_screen_data screen;								//定义一个screen（struct cross_screen_data类型的结构体），用来接收cross_screen返回的划屏数据	
	i = 10;
	while(i)
	{
		printf("[开始按钮回调函数： ] 请划屏测试划屏（cross_screen函数）,划 %d 次将退出程序\n",i--);
		
		
		screen = cross_screen();									//cross_screen会阻塞等待，从第一次触碰到屏幕开始读坐标，手指离开屏幕后返回，返回struct cross_screen_data类型的结构体
																			/***********************************
																			struct cross_screen_data
																				{
																					int x1;			//第一次触碰到的x坐标
																					int y1;			//第二次触碰到的y坐标
																					int x2;			//最后一次触碰到的x坐标
																					int y2;			//最后一次触碰到的y坐标
																					int delta_x;	//x方向上的差值，正值为向右划，负值为向左划
																					int delta_y;	//y方向上的差值，正值为向下划，负值为向上划
																				};
																			***********************************/
		printf("[开始按钮回调函数： ] cross_screen返回的结果\n");
		printf("[开始按钮回调函数： ] screen.x1 = %d\n",screen.x1);
		printf("[开始按钮回调函数： ] screen.y1 = %d\n",screen.y1);
		printf("[开始按钮回调函数： ] screen.x2 = %d\n",screen.x2);
		printf("[开始按钮回调函数： ] screen.y2 = %d\n",screen.y2);
		printf("[开始按钮回调函数： ] screen.delta_x = %4d,  %s\n",screen.delta_x,screen.delta_x > 0? "右划":"左划");
		printf("[开始按钮回调函数： ] screen.delta_y = %4d,  %s\n",screen.delta_y,screen.delta_y > 0? "下划":"上划");
		printf("\n");
	}
	
	
	return NULL;
}






















